﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Forms
{
    public partial class BaseForm : Form
    {
        public int TitleHeight = 54;
        bool IsLBtnDown = false;
        Point OldPoint;
        public List<BtnBox> BtnBoxes;
        int boxWidth = 38;
        int boxHeight = 21;
        int HoverIdex = -1;
        const int HTLEFT = 10;
        const int HTRIGHT = 11;
        const int HTTOP = 12;
        const int HTTOPLEFT = 13;
        const int HTTOPRIGHT = 14;
        const int HTBOTTOM = 15;
        const int HTBOTTOMLEFT = 0x10;
        const int HTBOTTOMRIGHT = 17;

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            switch (m.Msg)
            {
                case 0x0084:
                    if (WindowState != FormWindowState.Maximized)
                    {
                        Point vPoint = new Point((int)m.LParam & 0xFFFF,
                            (int)m.LParam >> 16 & 0xFFFF);
                        vPoint = PointToClient(vPoint);
                        if (vPoint.X <= 5)
                            if (vPoint.Y <= 5)
                                m.Result = (IntPtr)HTTOPLEFT;
                            else if (vPoint.Y >= ClientSize.Height - 5)
                                m.Result = (IntPtr)HTBOTTOMLEFT;
                            else m.Result = (IntPtr)HTLEFT;
                        else if (vPoint.X >= ClientSize.Width - 5)
                            if (vPoint.Y <= 5)
                                m.Result = (IntPtr)HTTOPRIGHT;
                            else if (vPoint.Y >= ClientSize.Height - 5)
                                m.Result = (IntPtr)HTBOTTOMRIGHT;
                            else m.Result = (IntPtr)HTRIGHT;
                        else if (vPoint.Y <= 5)
                            m.Result = (IntPtr)HTTOP;
                        else if (vPoint.Y >= ClientSize.Height - 5)
                            m.Result = (IntPtr)HTBOTTOM;
                    }
                    break;
                case 0x0201://鼠标左键按下的消息 
                    //m.Msg = 0x00A1;//更改消息为非客户区按下鼠标 
                    //m.LParam = IntPtr.Zero;//默认值 
                    //m.WParam = new IntPtr(2);//鼠标放在标题栏内 
                    break;
                default:
                    break;
            }
        }
        public BaseForm()
        {
            InitializeComponent();
            BtnBoxes = new List<BtnBox>();
            AddBtn("关闭", "Close", imageList.Images[2]);
            AddBtn("最大化", "Max", imageList.Images[1]);
            AddBtn("最小化", "Min", imageList.Images[0]);
            AddBtn("主题", "Theme");
            this.FormBorderStyle = FormBorderStyle.None;
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
        }

        void AddBtn(string txt, string name = null, Image image = null)
        {
            BtnBoxes.Add(new BtnBox() { Text = txt, Name = name == null ? txt : name, Image = image });
        }

        void DrawBtns(Graphics g)
        {
            int i = 1;
            if (HoverIdex >= 0 && HoverIdex < BtnBoxes.Count)
            {
                if (HoverIdex == 0)
                {
                    g.FillRectangle(new SolidBrush(Color.FromArgb(232, 88, 88)), new Rectangle(Width - (HoverIdex + 1) * boxWidth, 1, boxWidth, boxHeight));
                }
                else
                    g.DrawRectangle(new Pen(Color.FromArgb(200, 200, 200)), new Rectangle(Width - (HoverIdex + 1) * boxWidth, 1, boxWidth, boxHeight));
            }
            foreach (BtnBox btn in BtnBoxes)
            {
                if (btn.Image == null)
                {
                    Size TextSize = TextRenderer.MeasureText(btn.Text,Font);
                    g.DrawString(btn.Text, Font, new SolidBrush(Color.Black), new Point(Width - boxWidth * i + (boxWidth - TextSize.Width) / 2, (boxHeight - TextSize.Height) / 2));
                }
                else
                    g.DrawImage(btn.Image, new Point(Width - boxWidth * i++ + (boxWidth - btn.Image.Width) / 2, (boxHeight - btn.Image.Height) / 2));
            }
        }

        bool IsInTitleRect(Point point)
        {
            return point.Y <= TitleHeight;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(241,241,241)), new Rectangle(0, 0, Width, TitleHeight));
            e.Graphics.DrawRectangle(new Pen(Color.FromArgb(121,121,121)), new Rectangle(0, 0, Width - 1, Height - 1));
            DrawBtns(e.Graphics);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left)
            {
                if (IsInTitleRect(e.Location))
                {
                    if (!IsClickBtns(e.Location))
                    {
                        IsLBtnDown = true;
                        OldPoint = e.Location;
                    }
                }
            }
        }

        bool IsClickBtns(Point point)
        {
            if (point.X >= Width - BtnBoxes.Count * boxWidth)
            {
                if (point.Y<=boxHeight)
                {
                    return true;
                }
            }
            return false;
        }

        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            base.OnMouseDoubleClick(e);
            if (e.Y <= TitleHeight)
            {
                WindowState = WindowState == FormWindowState.Maximized ? FormWindowState.Normal : FormWindowState.Maximized;
            }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            if (e.Button == MouseButtons.Left)
            {
                IsLBtnDown = false;
                if (e.Y <= boxHeight)
                {
                    int index = (Width - e.X) / boxWidth;
                    if (index < BtnBoxes.Count && index >= 0)
                    {
                        if (BtnBoxes[index].Name == "Close")
                        {
                            Application.Exit();
                        }
                        else if (BtnBoxes[index].Name == "Min")
                        {
                            WindowState = FormWindowState.Minimized;
                            IsLBtnDown = false;
                        }
                        else if (BtnBoxes[index].Name == "Max")
                        {
                            WindowState = WindowState == FormWindowState.Maximized ? FormWindowState.Normal : FormWindowState.Maximized;
                        }
                    }
                }
                Invalidate();
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (IsLBtnDown)
            {
                this.Location = new Point(Location.X + e.Location.X - OldPoint.X, Location.Y + e.Location.Y - OldPoint.Y);
            }
            if (e.Y <= boxHeight)
            {
                int index = (Width - e.X) / boxWidth;
                if (HoverIdex != index)
                {
                    HoverIdex = index;
                    Invalidate();
                }
            }
            else
            {
                HoverIdex = -1;
                Invalidate();
            }
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            Invalidate();
        }
    }
}
